package com.tom.architect02.zframework.sandbox.impl;

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.tom.architect02.zframework.sandbox.base.BaseRequest;
import com.tom.architect02.zframework.sandbox.base.DbField;
import com.tom.architect02.zframework.sandbox.base.FileResponse;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

// API 29+ 存储框架方案。
public class MediaStoreAccessImp implements IFile {

//    真正对文件的操作  分区
    HashMap<String, Uri> uriMap = new HashMap<>(); // 类型缓存。
    //    限制  内置目录   data/data/
    public static final String AUDIO = "Audio";
    public static final String VIDEO = "Video";
    public static final String IMAGE = "Pictures";
    public static final String DOWNLOADS = "Downloads";//什么都可以放
    private static MediaStoreAccessImp sInstance;

    public static MediaStoreAccessImp getInstance() {
        if (sInstance == null) {
            synchronized (MediaStoreAccessImp.class) {
                if (sInstance == null) {
                    sInstance = new MediaStoreAccessImp();
                }
            }
        }
        return sInstance;
    }


    @SuppressLint("NewApi")
    private MediaStoreAccessImp() {
        //外置卡 对应图片的URI， 根据类型找到uri
        uriMap.put(AUDIO, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
        uriMap.put(VIDEO, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
        uriMap.put(IMAGE, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        uriMap.put(DOWNLOADS, MediaStore.Downloads.EXTERNAL_CONTENT_URI);
    }
    public static void setup() {
    }

    //Android R
    @Override
    public <T extends BaseRequest> FileResponse newCreateFile(Context context, T baseRequest) {
        // 创建文件/文件夹。
        Uri uri = uriMap.get(baseRequest.getType());
        ContentValues contentValues = objectConvertValues(baseRequest); // 读取注解的值
        Uri resultUri = context.getContentResolver().insert(uri, contentValues);
        if (resultUri != null) {
            Toast.makeText(context, "创建成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(context, "创建失败", Toast.LENGTH_SHORT).show();
        }
        FileResponse fileResponse = new FileResponse();
        fileResponse.setUri(resultUri);
        return fileResponse;
    }

    //  分区存储  性能上   比原先的  性能要低
    private <T extends BaseRequest> ContentValues objectConvertValues(T baseRequest) {
        ContentValues contentValues = new ContentValues();
        Field[] fields = baseRequest.getClass().getDeclaredFields();

        for (Field field : fields) {
            DbField dbField = field.getAnnotation(DbField.class); // 对标记进行处理。
            if (dbField == null) {
                continue;
            }
            String name = dbField.value();
            String value = null;
            String fieldName = field.getName();

            char firstLetter = Character.toUpperCase(fieldName.charAt(0)); // 首字母大写
            String theRest = fieldName.substring(1); // 非首字母保留。
            String methodName = "get" + firstLetter + theRest; // 组装get方法，然后反射执行。
            Log.i("tuch", "objectConvertValues: " + methodName);
            try {
                Method getMethod = baseRequest.getClass().getMethod(methodName);
                value = (String) getMethod.invoke(baseRequest);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(value)) {
                contentValues.put(name, value);
            }
        }
        return contentValues;
    }

    @Override
    public <T extends BaseRequest> FileResponse delete(Context context, T baseRequest) {
        Uri uri = query(context, baseRequest).getUri(); // 先查询到
        context.getContentResolver().delete(uri, null, null);
        return null;
    }

    @Override
    public <T extends BaseRequest> FileResponse renameTo(Context context, T where, T to) {
        Uri uri = query(context, where).getUri(); // 先查图片，得到唯一结果。
        // 对象转ContentValues。
        ContentValues contentValues = objectConvertValues(to);
        int code = context.getContentResolver().update(uri, contentValues, null, null);
        if (code > 0) {
            Toast.makeText(context, "更改成功", Toast.LENGTH_SHORT).show();
        }
        FileResponse fileResponse = new FileResponse();
        fileResponse.setUri(uri);
        return fileResponse;
    }

    @Override
    public <T extends BaseRequest> FileResponse copyFile(Context context, T baseRequest) {
        return null;
    }

    // 通过ContentURL 查询，做符合沙箱的查询操作。
    @Override
    public <T extends BaseRequest> FileResponse query(Context context, T baseRequest) {
        Uri uri = uriMap.get(baseRequest.getType());
        ContentValues contentValues = objectConvertValues(baseRequest);
        Condition condition = new Condition(contentValues); // 拼装查询指令
        String[] projection = new String[]{MediaStore.Images.Media._ID}; // id-> uri
        Cursor cursor = context.getContentResolver().query(uri, projection, condition.whereCasue, condition.whereArgs, null);
        Uri queryUri = null;
        if (cursor != null && cursor.moveToFirst()) {
            queryUri = ContentUris.withAppendedId(uri, cursor.getLong(0));
            Toast.makeText(context, "查询成功" + queryUri, Toast.LENGTH_SHORT).show();
            cursor.close();
        }
        FileResponse fileResponse = new FileResponse();
        fileResponse.setUri(queryUri); // 设置查询结果。
        return fileResponse;
    }

    private class Condition {
        private String whereCasue;  //image_url =?  AND   qq_number=?

        private String[] whereArgs;

        public Condition(ContentValues contentValues) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("1=1");
            ArrayList list = new ArrayList();//whereArgs里面的内容存入list
            //取所有的字段名，遍历map集合。
            Iterator<Map.Entry<String, Object>> set = contentValues.valueSet().iterator();
            while (set.hasNext()) {
                Map.Entry<String, Object> entry = set.next();
                String key = entry.getKey();
                String value = (String) entry.getValue();
                if (value != null) {
                    stringBuilder.append(" and " + key + " =? ");
                    list.add(value);
                }
            }
            this.whereCasue = stringBuilder.toString();
            this.whereArgs = (String[]) list.toArray(new String[list.size()]);
        }

    }
}
